package com.dylan.历史.领扣;

import java.util.function.IntConsumer;

/**
 * @author : ankang
 * @date : 2019/10/11 18:00
 * @Description :
 */
public class $1116打印0与奇偶数 {

    public static void main(String[] args) {
        IntConsumer ic = System.out::println;
        ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd(20);
        new Thread(() -> {
            try {
                zeroEvenOdd.zero(ic);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(() -> {
            try {
                zeroEvenOdd.even(ic);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(() -> {
            try {
                zeroEvenOdd.odd(ic);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }

    static class ZeroEvenOdd {
        private volatile int n;
        private volatile int m = 0;
        private volatile boolean flag = true;

        public ZeroEvenOdd(int n) {
            this.n = n;
        }

        // printNumber.accept(x) outputs "x", where x is an integer.
        public synchronized void zero(IntConsumer printNumber) throws InterruptedException {
            while(m<n) {
                if(flag) {
                    printNumber.accept(0);
                    flag = false;
                } else {
                    this.notifyAll();
                    this.wait();
                }
            }
            this.notifyAll();
        }

        public synchronized void even(IntConsumer printNumber) throws InterruptedException {
            while(m<n) {
                if(m%2==0) {
                    this.notifyAll();
                    this.wait();
                } else if(flag) {
                    this.notifyAll();
                    this.wait();
                } else {
                    printNumber.accept(++m);
                    flag = true;
                }
            }
            this.notifyAll();
        }

        public synchronized void odd(IntConsumer printNumber) throws InterruptedException {
            while(m<n) {
                if(m%2==1) {
                    this.notifyAll();
                    this.wait();
                } else if(flag) {
                    this.notifyAll();
                    this.wait();
                } else {
                    printNumber.accept(++m);
                    flag = true;
                }
            }
            this.notifyAll();
        }
    }
}
